using MediatR;
using Microsoft.EntityFrameworkCore;
using SupplierCustomerManagement.Infrastructure;
using SupplierCustomerManagement.Read.API.Applications.Commands.lambing;
using SupplierCustomerManagement.Read.API.Dtos.Lambing;

namespace SupplierCustomerManagement.Read.API.Applications.CommandHandlters.lambing
{
    public class GetLambingMonthlyStatsQueryHandler : IRequestHandler<GetLambingMonthlyStatsQuery, List<LambingMonthlyRowDto>>
    {
        private readonly SupplierDbContext _db;
        private readonly ILogger<GetLambingMonthlyStatsQueryHandler> _logger;

        public GetLambingMonthlyStatsQueryHandler(SupplierDbContext db, ILogger<GetLambingMonthlyStatsQueryHandler> logger)
        {
            _db = db;
            _logger = logger;
        }

        public async Task<List<LambingMonthlyRowDto>> Handle(GetLambingMonthlyStatsQuery request, CancellationToken cancellationToken)
        {
            if (!int.TryParse(request.year, out var year))
            {
                year = DateTime.UtcNow.Year;
            }

            int? monthInt = null;
            if (!string.IsNullOrWhiteSpace(request.month) && int.TryParse(request.month, out var m))
            {
                if (m >= 1 && m <= 12) monthInt = m;
            }

            var query = _db.LambingRecords.AsNoTracking().Where(r => r.LambingDate.Year == year);
            if (request.farmId.HasValue)
                query = query.Where(r => r.FarmId == request.farmId.Value);
            if (monthInt.HasValue)
                query = query.Where(r => r.LambingDate.Month == monthInt.Value);

            var grouped = await query
                .GroupBy(r => r.LambingDate.Month)
                .Select(g => new
                {
                    Month = g.Key,
                    LitterCount = g.Count(),
                    TotalLamb = g.Sum(x => x.TotalLambs),
                    LiveLamb = g.Sum(x => x.LiveLambs),
                    Healthy = g.Sum(x => x.HealthyLambs ?? 0),
                    Weak = g.Sum(x => x.WeakLambs ?? 0),
                    Deformed = g.Sum(x => x.DeformedLambs ?? 0),
                    Mummy = g.Sum(x => x.MummifiedFetuses ?? 0),
                    Abnormal = g.Sum(x => x.AbnormalFetuses ?? 0),
                    Stillbirth = g.Sum(x => x.DeadLambs)
                })
                .ToListAsync(cancellationToken);

            var map = grouped.ToDictionary(
                x => x.Month,
                x => new LambingMonthlyRowDto
                {
                    month = x.Month.ToString("D2"),
                    litterCount = x.LitterCount,
                    totalLamb = x.TotalLamb,
                    healthy = x.Healthy,
                    weak = x.Weak,
                    deformed = x.Deformed,
                    mummy = x.Mummy,
                    abnormal = x.Abnormal,
                    stillbirth = x.Stillbirth,
                    liveLamb = x.LiveLamb,
                    liveRate = x.TotalLamb == 0 ? 0 : Math.Round((decimal)x.LiveLamb / x.TotalLamb, 4),
                    healthy1 = null,
                    over117 = null,
                    less111 = null,
                    liveCount1 = null,
                    liveCount2 = null,
                    weanedEwe = null,
                    weanedTotal = null,
                    weaned7Days = null
                }
            );

            var result = new List<LambingMonthlyRowDto>();
            if (monthInt.HasValue)
            {
                // 仅返回指定月份
                if (map.TryGetValue(monthInt.Value, out var row))
                {
                    result.Add(row);
                }
                else
                {
                    result.Add(new LambingMonthlyRowDto
                    {
                        month = monthInt.Value.ToString("D2"),
                        litterCount = 0,
                        totalLamb = 0,
                        liveLamb = 0,
                        liveRate = 0
                    });
                }
            }
            else
            {
                // 返回全年 12 个月
                for (int i = 1; i <= 12; i++)
                {
                    if (map.TryGetValue(i, out var row))
                    {
                        result.Add(row);
                    }
                    else
                    {
                        result.Add(new LambingMonthlyRowDto
                        {
                            month = i.ToString("D2"),
                            litterCount = 0,
                            totalLamb = 0,
                            liveLamb = 0,
                            liveRate = 0
                        });
                    }
                }
            }

            return result.OrderBy(r => r.month).ToList();
        }
    }
}
